home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / win / pascal / ctl3d_p.exe / CTL3D.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-03-18  |  26.0 KB  |  947 lines

  1. Unit Ctl3D;
  2.  
  3. {****************************************************************************}
  4. {                                                                            }
  5. { Unit:    CTL3D                                                             }
  6. { Version: 1.0                                                               }
  7. { Source:  Borland Pascal 7.0                                                }
  8. { Author:  Steve Hamer-Moss, CoCo Systems Ltd.                               }
  9. { Date:    February 1993                                                     }
  10. {                                                                            }
  11. { Purpose:                                                                   }
  12. {   BP7 interface unit for Microsoft's CTL3D dynamic link library. Allows    }
  13. {   BP7 applications to use Microsoft-standard 3D dialog boxes and controls, }
  14. {   even in parallel with BWCC (e.g., for use with common dialogs).          }
  15. {                                                                            }
  16. {****************************************************************************}
  17.  
  18. {$C MOVEABLE PRELOAD DISCARDABLE}
  19.  
  20. Interface
  21.  
  22. Uses
  23.  
  24.    CommDlg,
  25.    ODialogs,
  26.    OWindows,
  27.    WinDOS,
  28.    WinProcs,
  29.     WinTypes;
  30.  
  31. Const
  32.  
  33.                                                    {Messages sent by CTL3D...}
  34.     wm_DlgBorder                =    wm_User + 3567;
  35.    wm_DlgSubclass                =    wm_User + 3568;
  36.  
  37. Type
  38.  
  39.    T3dApplication                =
  40.    object(TApplication)                        {Main Application object}
  41.       Public
  42.       Destructor Done; Virtual;
  43.        Constructor Init (AName : PChar; Auto31, Borders3D, CommDlgs3D : Boolean);
  44.    end;
  45.  
  46.     T3dDialog                    =
  47.     object(TDialog)                            {Main dialog object}
  48.       Public
  49.       Procedure WMCtlColor (var Msg : TMessage); virtual wm_First + wm_CtlColor;
  50.       Procedure WMDlgBorder (var Msg : TMessage); virtual wm_First + wm_DlgBorder;
  51.       Procedure WMInitDialog (var Msg : TMessage); virtual wm_First + wm_InitDialog;
  52.       Procedure WMNCActivate (var Msg : TMessage); virtual wm_First + wm_NCActivate;
  53.       Procedure WMNCPaint (var Msg : TMessage); virtual wm_First + wm_NCPaint;
  54.       Procedure WMSetText (var Msg : TMessage); virtual wm_First + wm_SetText;
  55.    end;
  56.  
  57.    T3dMDIWindow                =
  58.    object(TMDIWindow)                        {Main MDI window object}
  59.         Procedure WMSysColorChange (var Msg : TMessage); virtual wm_First + wm_SysColorChange;
  60.    end;
  61.  
  62.    T3dWindow                    =                {Main window object}
  63.    object(TWindow)
  64.         Procedure WMSysColorChange (var Msg : TMessage); virtual wm_First + wm_SysColorChange;
  65.    end;
  66.  
  67.                                                     {Replacement common dialog functions ...}
  68. Function ChooseColor3D (var CC : TChooseColor) : Bool;
  69. Function ChooseFont3D (var CF : TChooseFont) : Bool;
  70. Function FindText3D (var FR : TFindReplace) : HWnd;
  71. Function GetOpenFilename3D (var OpenFile : TOpenFileName) : Bool;
  72. Function GetSaveFilename3D (var OpenFile : TOpenFileName) : Bool;
  73. Function PrintDlg3D (var PD : TPrintDlg) : Bool;
  74. Function ReplaceText3D (var FR : TFindReplace) : HWnd;
  75.  
  76. Function Ctl3dIsEnabled : Boolean;
  77.  
  78. Implementation
  79.  
  80. Const
  81.  
  82.     dwl_MsgResult                =    0;
  83.     hInstance_Error            =    THandle(32);
  84.     sem_NoOpenFileErrorBox    =    $8000;
  85.  
  86.     Base_Version                =    $0009;
  87.  
  88. Const
  89.  
  90.    Ctl3dDLLName                =    'CTL3D.DLL';
  91.  
  92.     Ctl3D_Buttons                =    $0001;
  93.     Ctl3D_Listboxes            =    $0002;
  94.     Ctl3D_Edits                    =    $0004;
  95.     Ctl3D_Combos                =    $0008;
  96.     Ctl3D_StaticTexts            =    $0010;
  97.     Ctl3D_StaticFrames        =    $0020;
  98.     Ctl3D_All                    =    $FFFF;
  99.  
  100.    Ctl3D_Border                =    1;
  101.    Ctl3D_NoBorder                =    0;
  102.    Ctl3D_NoSubclass            =    0;
  103.    Ctl3D_Subclass                =    1;
  104.  
  105.                                                    {Names of CTL3D exported functions ...}
  106.     Ctl3dAutoSubClassName    =    'CTL3DAUTOSUBCLASS';
  107.     Ctl3dColorChangeName        =    'CTL3DCOLORCHANGE';
  108.     Ctl3dCtlColorExName        =    'CTL3DCTLCOLOREX';
  109.     Ctl3dEnabledName            =    'CTL3DENABLED';
  110.     Ctl3dDlgFramePaintName    =    'CTL3DDLGFRAMEPAINT';
  111.     Ctl3dGetVerName            =    'CTL3DGETVER';
  112.     Ctl3dRegisterName            =    'CTL3DREGISTER';
  113.     Ctl3dSubclassDlgName        =    'CTL3DSUBCLASSDLG';
  114.     Ctl3dSubclassCtlName        =    'CTL3DSUBCLASSCTL';
  115.     Ctl3dUnregisterName        =    'CTL3DUNREGISTER';
  116.  
  117. Type
  118.  
  119.                                                    {CTL3D exported function templates ...}
  120.     TCtl3dAutoSubclass        =    Function (Instance : THandle) : Bool;
  121.     TCtl3dColorChange            =    Function : Bool;
  122.     TCtl3dCtlColorEx            =    Function (Message, wParam : Word; lParam : LongInt) : HBrush;
  123.     TCtl3dEnabled                =    Function : Bool;
  124.    TCtl3dDlgFramePaint        =    Function (HWindow : HWnd; Message, wParam : Word; lParam : LongInt) : LongInt;
  125.     TCtl3dGetVer                =    Function : Word;
  126.     TCtl3dRegister                =    Function (Instance : THandle): Bool;
  127.     TCtl3dSubclassCtl            =    Function (HWindow : HWnd) : Bool;
  128.     TCtl3dSubclassDlg            =    Function (HWindow : HWnd; GrBits : Word) : Bool;
  129.     TCtl3dUnregister            =    Function (Instance : THandle): Bool;
  130.  
  131.     TCommDlgHook                =    function (Wnd: HWnd; Msg, wParam: Word; lParam: LongInt): Word;
  132.  
  133. Var
  134.  
  135.                                                    {Variables to hold addresses of CTL3D
  136.                                                      exported functions ...}
  137.     Ctl3dAutoSubclass            :    TCtl3dAutoSubclass;
  138.     Ctl3dColorChange            :    TCtl3dColorChange;
  139.     Ctl3dCtlColorEx            :    TCtl3dCtlColorEx;
  140.     Ctl3dEnabled                :    TCtl3dEnabled;
  141.    Ctl3dDlgFramePaint        :    TCtl3dDlgFramePaint;
  142.     Ctl3dGetVer                    :    TCtl3dGetVer;
  143.     Ctl3dRegister                :    TCtl3dRegister;
  144.     Ctl3dSubclassDlg            :    TCtl3dSubclassDlg;
  145.     Ctl3dSubclassCtl            :    TCtl3dSubclassCtl;
  146.     Ctl3dUnregister            :    TCtl3dUnregister;
  147.  
  148. Const
  149.  
  150.    A31                            :    Boolean = True;        {True if Auto-subclassing}
  151.    B3D                            :    Boolean = False;        {True if using 3D borders}
  152.    CD3D                            :    Boolean = True;        {True if using 3D common dialogs}
  153.    Ctl3dHandle                    :    THandle = 0;            {Handle to CTL3D DLL}
  154.    UseCtl3d                        :    Boolean = False;        {True if using 3D controls}
  155.  
  156. Var
  157.  
  158.    UserHookProc                :    TCommDlgHook;            {Address of user's hook proc,
  159.                                                                      if any, for common dialogs}
  160.     WinVersion                    :    Word;                        {Windows version number}
  161.     Win30                            :    Boolean;                    {True if Windows 3.0}
  162.  
  163. {* ------------------------ Ctl3dIsEnabled ------------------------- *}
  164.  
  165. Function Ctl3dIsEnabled : Boolean;
  166. {
  167.     Returns True if unit has enabled use of 3D controls
  168. }
  169. begin
  170.     Ctl3dIsEnabled := UseCtl3d
  171. end;
  172.  
  173. {* -------------------------- HookProc3D --------------------------- *}
  174.  
  175. Function HookProc3D (HWindow : HWnd; Msg, wParam : Word; lParam : LongInt) : Word; Export;
  176. {
  177.     Common hook procedure for common dialogs. Implements 3D controls for all
  178.    common dialogs when used via the replacement common dialog functions
  179.    contained in this unit.
  180.  
  181.    If the user has also defined a hook procedure for use with the current
  182.    common dialog function call, its address is now in the unit variable
  183.     UserHookProc. The user hook is then called before this procedure does
  184.     its 3D stuff.
  185. }
  186. Type
  187.  
  188.     TIntPtr                =    ^Integer;
  189.  
  190. begin
  191.  
  192.                                                    {Call user hook procedure first}
  193.    if Assigned(@UserHookProc)
  194.    then
  195.        HookProc3D := UserHookProc(HWindow,Msg,wParam,lParam)
  196.    else
  197.        HookProc3D := 0;
  198.  
  199.    if UseCtl3D and CD3D
  200.    then                                            {Now do the 3D stuff ...}
  201.         Case Msg of
  202.  
  203.             wm_InitDialog:
  204.                 if Assigned(@Ctl3dSubclassDlg)
  205.                 then                                {Initialise: Subclass the common dialog
  206.                                                      via CTL3D}
  207.                     Ctl3dSubclassDlg(HWindow,Ctl3D_All);
  208.  
  209.          wm_CtlColor:
  210.              if Assigned(@Ctl3dCtlColorEx)
  211.             then                                {Colour setup: tell CTL3D to do graying}
  212.                 HookProc3D := Ctl3dCtlColorEx(Msg,wParam,lParam);
  213.  
  214.          wm_DlgBorder:
  215.              if B3D
  216.                 then                                {Border: tell CTL3D to paint a 3D border}
  217.                     TIntPtr(lParam)^ := Ctl3D_Border
  218.             else                                {Border: tell CTL3D to use a modal border}
  219.                     TIntPtr(lParam)^ := Ctl3D_NoBorder;
  220.  
  221.          wm_NCActivate,
  222.          wm_NCPaint,
  223.          wm_SetText:
  224.              if B3D and Assigned(@Ctl3dDlgFramePaint)
  225.             then
  226.             begin                                {This will ensure CTL3D paints the controls
  227.                                                      correctly ...}
  228.  
  229.                SetWindowLong(HWindow,dwl_MsgResult,
  230.                                       Ctl3dDlgFramePaint(HWindow,Msg,wParam,lParam));
  231.                     HookProc3D := 1
  232.  
  233.             end
  234.  
  235.       end
  236.  
  237. end;
  238.  
  239. {* ------------------------- ChooseColor3D -------------------------- *}
  240.  
  241. Function ChooseColor3D (var CC : TChooseColor) : Bool;
  242. {
  243.     Replacement for common dialog function ChooseColor. Sets up local
  244.    hook procedure for 3D painting (saving address of any user hook proc
  245.     into UserHookProc) and then calls ChooseColor.
  246. }
  247. begin
  248.  
  249.    if not (UseCtl3D and CD3D)
  250.    then
  251.        ChooseColor3D := ChooseColor(CC)
  252.     else
  253.    begin
  254.  
  255.        if ((CC.Flags and cc_EnableHook) = cc_EnableHook)
  256.        then
  257.             UserHookProc := CC.lpfnHook
  258.        else
  259.        begin
  260.  
  261.          UserHookProc := nil;
  262.             CC.Flags := CC.Flags or cc_EnableHook
  263.  
  264.        end;
  265.  
  266.        TFarProc(@CC.lpfnHook) := MakeProcInstance(TFarProc(@HookProc3D),hInstance);
  267.         ChooseColor3D := ChooseColor(CC);
  268.        FreeProcInstance(TFarProc(@CC.lpfnHook))
  269.  
  270.    end
  271.  
  272. end;
  273.  
  274. {* -------------------------- ChooseFont3D -------------------------- *}
  275.  
  276. Function ChooseFont3D (var CF : TChooseFont) : Bool;
  277. {
  278.     Replacement for common dialog function ChooseFont. Sets up local
  279.    hook procedure for 3D painting (saving address of any user hook proc
  280.     into UserHookProc) and then calls ChooseFont.
  281. }
  282. begin
  283.  
  284.    if not (UseCtl3D and CD3D)
  285.    then
  286.        ChooseFont3D := ChooseFont(CF)
  287.     else
  288.    begin
  289.  
  290.         if    ((CF.Flags and cf_EnableHook) = cf_EnableHook)
  291.        then
  292.             UserHookProc := CF.lpfnHook
  293.        else
  294.        begin
  295.  
  296.          UserHookProc := nil;
  297.             CF.Flags := CF.Flags or cf_EnableHook
  298.  
  299.        end;
  300.  
  301.        TFarProc(@CF.lpfnHook) := MakeProcInstance(TFarProc(@HookProc3D),hInstance);
  302.        ChooseFont3D := ChooseFont(CF);
  303.        FreeProcInstance(TFarProc(@CF.lpfnHook))
  304.  
  305.    end
  306.  
  307. end;
  308.  
  309. {* --------------------------- FindText3D --------------------------- *}
  310.  
  311. Function FindText3D (var FR : TFindReplace) : HWnd;
  312. {
  313.     Replacement for common dialog function FindText. Sets up local
  314.    hook procedure for 3D painting (saving address of any user hook proc
  315.     into UserHookProc) and then calls FindText.
  316. }
  317. begin
  318.  
  319.    if not (UseCtl3D and CD3D)
  320.    then
  321.        FindText3D := FindText(FR)
  322.     else
  323.    begin
  324.  
  325.         if ((FR.Flags and fr_EnableHook) = fr_EnableHook)
  326.        then
  327.             UserHookProc := FR.lpfnHook
  328.        else
  329.        begin
  330.  
  331.          UserHookProc := nil;
  332.             FR.Flags := FR.Flags or fr_EnableHook
  333.  
  334.        end;
  335.  
  336.        TFarProc(@FR.lpfnHook) := MakeProcInstance(TFarProc(@HookProc3D),hInstance);
  337.        FindText3D := FindText(FR);
  338.        FreeProcInstance(TFarProc(@FR.lpfnHook))
  339.  
  340.    end
  341.  
  342. end;
  343.  
  344. {* ----------------------- GetOpenFilename3D ------------------------ *}
  345.  
  346. Function GetOpenFilename3D (var OpenFile : TOpenFileName) : Bool;
  347. {
  348.     Replacement for common dialog function GetOpenFileName. Sets up local
  349.    hook procedure for 3D painting (saving address of any user hook proc
  350.     into UserHookProc) and then calls GetOpenFileName.
  351. }
  352. begin
  353.  
  354.    if not (UseCtl3D and CD3D)
  355.    then
  356.        GetOpenFileName3D := GetOpenFileName(OpenFile)
  357.     else
  358.    begin
  359.  
  360.         if ((OpenFile.Flags and ofn_EnableHook) = ofn_EnableHook)
  361.        then
  362.             UserHookProc := OpenFile.lpfnHook
  363.        else
  364.        begin
  365.  
  366.          UserHookProc := nil;
  367.             OpenFile.Flags := OpenFile.Flags or ofn_EnableHook
  368.  
  369.        end;
  370.  
  371.        TFarProc(@OpenFile.lpfnHook) := MakeProcInstance(TFarProc(@HookProc3D),hInstance);
  372.        GetOpenFileName3D := GetOpenFileName(OpenFile);
  373.        FreeProcInstance(TFarProc(@OpenFile.lpfnHook))
  374.  
  375.    end
  376.  
  377. end;
  378.  
  379. {* ----------------------- GetSaveFilename3D ----------------------- *}
  380.  
  381. Function GetSaveFilename3D (var OpenFile : TOpenFileName) : Bool;
  382. {
  383.     Replacement for common dialog function GetSaveFileName. Sets up local
  384.    hook procedure for 3D painting (saving address of any user hook proc
  385.     into UserHookProc) and then calls GetSaveFileName.
  386. }
  387. begin
  388.  
  389.    if not (UseCtl3D and CD3D)
  390.    then
  391.        GetSaveFileName3D := GetSaveFileName(OpenFile)
  392.     else
  393.    begin
  394.  
  395.         if ((OpenFile.Flags and ofn_EnableHook) = ofn_EnableHook)
  396.        then
  397.             UserHookProc := OpenFile.lpfnHook
  398.        else
  399.        begin
  400.  
  401.          UserHookProc := nil;
  402.             OpenFile.Flags := OpenFile.Flags or ofn_EnableHook
  403.  
  404.        end;
  405.  
  406.        TFarProc(@OpenFile.lpfnHook) := MakeProcInstance(TFarProc(@HookProc3D),hInstance);
  407.        GetSaveFileName3D := GetOpenFileName(OpenFile);
  408.        FreeProcInstance(TFarProc(@OpenFile.lpfnHook))
  409.  
  410.    end
  411.  
  412. end;
  413.  
  414. {* --------------------------- PrintDlg3d -------------------------- *}
  415.  
  416. Function PrintDlg3D (var PD : TPrintDlg) : Bool;
  417. {
  418.     Replacement for common dialog function PrintDlg. Sets up local
  419.    hook procedure for 3D painting (saving address of any user hook proc
  420.     into UserHookProc) and then calls PrintDlg.
  421. }
  422. begin
  423.  
  424.    if not (UseCtl3D and CD3D)
  425.    then
  426.        PrintDlg3D := PrintDlg(PD)
  427.     else
  428.    begin
  429.  
  430.         if ((PD.Flags and pd_EnablePrintHook) = pd_EnablePrintHook)
  431.        then
  432.             UserHookProc := TCommDlgHook(PD.lpfnPrintHook)
  433.        else
  434.        begin
  435.  
  436.          UserHookProc := nil;
  437.             PD.Flags := PD.Flags or pd_EnablePrintHook
  438.  
  439.        end;
  440.  
  441.         if ((PD.Flags and pd_EnableSetupHook) = pd_EnableSetupHook)
  442.        then
  443.             UserHookProc := TCommDlgHook(PD.lpfnSetupHook)
  444.        else
  445.        begin
  446.  
  447.          UserHookProc := nil;
  448.             PD.Flags := PD.Flags or pd_EnableSetupHook
  449.  
  450.        end;
  451.  
  452.        TFarProc(@PD.lpfnPrintHook) := MakeProcInstance(TFarProc(@HookProc3D),hInstance);
  453.        PD.lpfnSetupHook := PD.lpfnPrintHook;
  454.        PrintDlg3D := PrintDlg(PD);
  455.        FreeProcInstance(TFarProc(@PD.lpfnPrintHook))
  456.  
  457.    end
  458.  
  459. end;
  460.  
  461. {* ------------------------- ReplaceText3d ------------------------- *}
  462.  
  463. Function ReplaceText3D (var FR : TFindReplace) : HWnd;
  464. {
  465.     Replacement for common dialog function ReplaceText. Sets up local
  466.    hook procedure for 3D painting (saving address of any user hook proc
  467.     into UserHookProc) and then calls ReplaceText.
  468. }
  469. begin
  470.  
  471.    if not (UseCtl3D and CD3D)
  472.    then
  473.        ReplaceText3D := ReplaceText(FR)
  474.     else
  475.    begin
  476.  
  477.         if ((FR.Flags and fr_EnableHook) = fr_EnableHook)
  478.        then
  479.             UserHookProc := FR.lpfnHook
  480.        else
  481.        begin
  482.  
  483.          UserHookProc := nil;
  484.             FR.Flags := FR.Flags or fr_EnableHook
  485.  
  486.        end;
  487.  
  488.        TFarProc(@FR.lpfnHook) := MakeProcInstance(TFarProc(@HookProc3D),hInstance);
  489.        ReplaceText3D := ReplaceText(FR);
  490.        FreeProcInstance(TFarProc(@FR.lpfnHook))
  491.  
  492.    end
  493.  
  494. end;
  495.  
  496. {* ------------------------ CloseDownCtl3d ------------------------- *}
  497.  
  498. Procedure CloseDownCtl3d;
  499. {
  500.     Application cleanup code called from T3DApplication.Done. Frees the
  501.    CTL3D library for this app.
  502. }
  503. begin
  504.  
  505.     if Ctl3dHandle >= hInstance_Error
  506.     then
  507.         FreeLibrary(Ctl3dHandle);
  508.  
  509.       UseCtl3d := False;
  510.     @Ctl3dAutoSubclass := nil;
  511.     @Ctl3dColorChange := nil;
  512.     @Ctl3dCtlColorEx := nil;
  513.     @Ctl3dEnabled := nil;
  514.    @Ctl3dDlgFramePaint := nil;
  515.     @Ctl3dGetVer := nil;
  516.     @Ctl3dRegister := nil;
  517.     @Ctl3dSubclassDlg := nil;
  518.     @Ctl3dSubclassCtl := nil;
  519.     @Ctl3dUnregister := nil
  520.  
  521. end;
  522.  
  523. {* -------------------------- DLLExists ---------------------------- *}
  524.  
  525. Function DLLExists (FN : PChar; AName : PChar) : Boolean;
  526. {
  527.     General routine that looks for a DLL file. Used only when running
  528.     under Windows 3.0 (to prevent the 'Cannot find ...' system modal
  529.     dialog box that occurs under Win 3.0 if the DLL is not present when
  530.     calling LoadLibrary).
  531.  
  532.    Looks for named DLL in the following order:
  533.  
  534.    (1) The current directory,
  535.    (2) The windows directory,
  536.    (3) The windows system directory,
  537.    (4) Anywhere in the DOS Path.
  538.  
  539.    Returns true if found.
  540. }
  541. const
  542.  
  543.     TempLen            =    255;
  544.  
  545. var
  546.  
  547.    Dest                :    array[0..fsPathName] of char;
  548.    Temp                :    array[0..TempLen] of char;
  549.    TExt                :    array[0..fsExtension] of char;
  550.     TName                :    array[0..fsFileName] of char;
  551.  
  552. begin
  553.  
  554.    DLLExists := False;
  555.    Temp[0] := #0;
  556.  
  557.    FileSearch(Dest,FN,Temp);
  558.  
  559.    if Dest[0] <> #0
  560.    then
  561.        DLLExists := True
  562.    else
  563.    begin
  564.  
  565.        GetWindowsDirectory(Temp,TempLen);
  566.        FileSearch(Dest,FN,Temp);
  567.  
  568.        if Dest[0] <> #0
  569.        then
  570.            DLLExists := True
  571.       else
  572.       begin
  573.  
  574.            GetSystemDirectory(Temp,TempLen);
  575.            FileSearch(Dest,FN,Temp);
  576.  
  577.            if Dest[0] <> #0
  578.            then
  579.                DLLExists := True
  580.          else
  581.          begin
  582.  
  583.                GetModuleFileName(GetModuleHandle(AName),Temp,SizeOf(Temp));
  584.                 FileSplit(Temp,Temp,TName,TExt);
  585.                 FileSearch(Dest,FN,Temp);
  586.  
  587.                if Dest[0] <> #0
  588.                then
  589.                    DLLExists := True
  590.              else
  591.             begin
  592.  
  593.                    FileSearch(Dest,FN,GetEnvVar('PATH'));
  594.  
  595.                    if Dest[0] <> #0
  596.                    then
  597.                        DLLExists := True
  598.  
  599.             end
  600.  
  601.             end
  602.  
  603.         end
  604.  
  605.    end
  606.  
  607. end;
  608.  
  609. {* -------------------------- SetupCtl3d --------------------------- *}
  610.  
  611. Function SetupCtl3d (AName : PChar; Auto31, Borders3D, CommDlgs3D : Boolean) : Boolean;
  612. {
  613.     Initialises this unit for T3DApplication.Init.
  614. }
  615. begin
  616.  
  617.    SetupCtl3d := True;                        {Assume all will be OK}
  618.  
  619.    if UseCtl3d
  620.    then                                            {Already set up! Finish now}
  621.        Exit;
  622.  
  623.     if Win30
  624.    then
  625.    begin                                            {Running under Win 3.0: look for CTL3D.DLL
  626.                                                      without causing user error}
  627.  
  628.         if DLLExists(Ctl3dDLLName,AName)
  629.         then
  630.             Ctl3dHandle := LoadLibrary(Ctl3dDLLName)
  631.       else
  632.           Ctl3dHandle := 0
  633.  
  634.    end
  635.    else
  636.    begin                                            {Running under Win 3.1: look for CTL3D.DLL
  637.                                                      without error message}
  638.  
  639.         SetErrorMode(sem_NoOpenFileErrorBox);
  640.        Ctl3dHandle := LoadLibrary(Ctl3dDLLName);
  641.         SetErrorMode(0)
  642.  
  643.    end;
  644.  
  645.    if Ctl3dHandle >= hInstance_Error
  646.    then
  647.    begin                                            {Found CTL3D... }
  648.  
  649.                                                   {get addresses of CTL3D exported functions}
  650.        @Ctl3dAutoSubclass := GetProcAddress(Ctl3dHandle,Ctl3dAutoSubClassName);
  651.        @Ctl3dColorChange := GetProcAddress(Ctl3dHandle,Ctl3dColorChangeName);
  652.        @Ctl3dCtlColorEx := GetProcAddress(Ctl3dHandle,Ctl3dCtlColorExName);
  653.        @Ctl3dEnabled := GetProcAddress(Ctl3dHandle,Ctl3dEnabledName);
  654.       @Ctl3dDlgFramePaint := GetProcAddress(Ctl3dHandle,Ctl3dDlgFramePaintName);
  655.        @Ctl3dGetVer := GetProcAddress(Ctl3dHandle,Ctl3dGetVerName);
  656.        @Ctl3dRegister := GetProcAddress(Ctl3dHandle,Ctl3dRegisterName);
  657.        @Ctl3dSubclassDlg := GetProcAddress(Ctl3dHandle,Ctl3dSubclassDlgName);
  658.        @Ctl3dSubclassCtl := GetProcAddress(Ctl3dHandle,Ctl3dSubclassCtlName);
  659.        @Ctl3dUnregister := GetProcAddress(Ctl3dHandle,Ctl3dUnregisterName);
  660.  
  661.                                                   {Register this app instance with DLL}
  662.        UseCtl3D := Ctl3dRegister(hInstance);
  663.  
  664.       if UseCtl3D
  665.         then                                        {Registration successful - ensure we have
  666.                                                      a recent enough version of CTL3D, and
  667.                                                      calling app wants to use 3D controls}
  668.           UseCtl3d := Ctl3dEnabled and (Ctl3dGetVer >= Base_Version);
  669.  
  670.       if not UseCtl3D
  671.       then                                        {Not all conditions met - tidy up}
  672.           CloseDownCtl3d
  673.       else
  674.       begin
  675.  
  676.          A31 := Auto31;                        {Save Auto-subclass state}
  677.          B3D := Borders3D;                    {Save 3D borders state}
  678.          CD3D := CommDlgs3D;                {Save 3D common dialogs state}
  679.  
  680.           if (not Win30) and A31
  681.          then                                    {CTL3D does not support auto-subclassing
  682.                                                      for Windows 3.0}
  683.              Ctl3dAutoSubclass(hInstance)
  684.  
  685.       end
  686.  
  687.    end;
  688.  
  689.    SetupCtl3d := UseCtl3d                    {Return True if initialised OK}
  690.  
  691. end;
  692.  
  693. {****************************************************************************}
  694. {*                                                                          *}
  695. {* Object:   T3dApplication                                                 *}
  696. {*                                                                          *}
  697. {*                                                                          *}
  698. {* Replacement object for TApplication. Contains replacement Init and Done  *}
  699. {* methods to ensure proper set-up/close-down of 3D interface code.         *}
  700. {*                                                                          *}
  701. {****************************************************************************}
  702.  
  703. {* ------------------------- T3dApplication.Done -------------------------- *}
  704.  
  705. Destructor T3dApplication.Done;
  706. {
  707.     Deregisters the application instance from CTL3D DLL and tidies up.
  708. }
  709. begin
  710.  
  711.    if UseCtl3d
  712.    then
  713.    begin
  714.  
  715.       Ctl3dUnregister(hInstance);
  716.        CloseDownCtl3d
  717.  
  718.    end;
  719.  
  720.     inherited Done
  721.  
  722. end;
  723.  
  724. {* ------------------------- T3dApplication.Init -------------------------- *}
  725.  
  726. Constructor T3dApplication.Init (AName : PChar; Auto31, Borders3D, CommDlgs3D : Boolean);
  727. {
  728.     Takes care of application-level setup for use of 3D dialogs. Parameters are as
  729.    follows:
  730.  
  731.    AName:        Application name (as for TApplication.Init)
  732.    Auto31:     True if CTL3D is to auto-subclass dialogs under Windows 3.1
  733.    Borders3D:    True to use 3D bordres, False to use modal dialog borders
  734.    CommDlgs3D: True if common dialogs are to be 3D (if Auto31 is True, common
  735.                     dialogs are ALWAYS* 3D)
  736. }
  737. begin
  738.  
  739.     inherited Init(AName);
  740.    SetupCtl3d(AName,Auto31,Borders3D,CommDlgs3D)
  741.  
  742. end;
  743.  
  744. {****************************************************************************}
  745. {*                                                                          *}
  746. {* Object:   T3dDialog                                                      *}
  747. {*                                                                          *}
  748. {* Replacement object for TDialog. Controls CTL3D subclassing of individual *}
  749. {* dialogs, and setup of the correct type of dialog border.                 *}
  750. {*                                                                          *}
  751. {****************************************************************************}
  752.  
  753. {* ------------------------ T3dDialog.WMCtlColor ------------------------- *}
  754.  
  755. Procedure T3dDialog.WMCtlColor (var Msg : TMessage);
  756. {
  757.     Ensures proper color setup for 3D dialog.
  758. }
  759. begin
  760.  
  761.     if (not BWCCClassNames) and UseCtl3d and Assigned(@Ctl3dCtlColorEx)
  762.    then
  763.        With Msg
  764.       do
  765.           Result := Ctl3dCtlColorEx(Message,wParam,lParam)
  766.  
  767. end;
  768.  
  769. {* ------------------------ T3dDialog.WMDlgBorder ------------------------ *}
  770.  
  771. Procedure T3dDialog.WMDlgBorder (var Msg : TMessage);
  772. {
  773.     Controls use of 3D border.
  774. }
  775. Type
  776.  
  777.     TIntPtr                =    ^Integer;
  778.  
  779. begin
  780.  
  781.     if (not BWCCClassNames) and UseCtl3d
  782.    then
  783.    begin
  784.  
  785.         if B3D
  786.       then
  787.           TIntPtr(Msg.lParam)^ := Ctl3D_Border
  788.       else
  789.           TIntPtr(Msg.lParam)^ := Ctl3D_NoBorder
  790.  
  791.    end
  792.  
  793. end;
  794.  
  795. {* ------------------------ T3dDialog.WMInitDialog ------------------------ *}
  796.  
  797. Procedure T3dDialog.WMInitDialog (var Msg : TMessage);
  798. {
  799.     Causes CTL3D to subclass dialog.
  800. }
  801. begin
  802.  
  803.    if (not BWCCClassNames) and UseCtl3d
  804.    then
  805.        Ctl3dSubclassDlg(hWindow,Ctl3D_All);
  806.  
  807.     inherited WMInitDialog(Msg)
  808.  
  809. end;
  810.  
  811. {* ------------------------ T3dDialog.WMNCActivate ------------------------ *}
  812.  
  813. Procedure T3dDialog.WMNCActivate (var Msg : TMessage);
  814. {
  815.    Ensures proper frame painting of 3D dialogs on mouse activation.
  816. }
  817. begin
  818.  
  819.    if (not BWCCClassNames) and UseCtl3d and B3D and IsModal and
  820.         Assigned(@Ctl3dDlgFramePaint)
  821.    then
  822.         With Msg
  823.        do
  824.       begin
  825.  
  826.             SetWindowLong(HWindow,dwl_MsgResult,
  827.                               Ctl3dDlgFramePaint(HWindow,Message,wParam,lParam));
  828.             Result := 1
  829.  
  830.       end
  831.    else
  832.        DefWndProc(Msg)
  833.  
  834. end;
  835.  
  836. {* ------------------------- T3dDialog.WMNCPaint -------------------------- *}
  837.  
  838. Procedure T3dDialog.WMNCPaint (var Msg : TMessage);
  839. {
  840.     ... again, part of proper 3D painting
  841. }
  842. begin
  843.  
  844.    if (not BWCCClassNames) and UseCtl3d and B3D and IsModal and
  845.         Assigned(@Ctl3dDlgFramePaint)
  846.    then
  847.         With Msg
  848.        do
  849.       begin
  850.  
  851.             SetWindowLong(HWindow,dwl_MsgResult,
  852.                               Ctl3dDlgFramePaint(HWindow,Message,wParam,lParam));
  853.             Result := 1
  854.  
  855.       end
  856.    else
  857.        DefWndProc(Msg)
  858.  
  859. end;
  860.  
  861. {* ------------------------- T3dDialog.WMSetText -------------------------- *}
  862.  
  863. Procedure T3dDialog.WMSetText (var Msg : TMessage);
  864. {
  865. {
  866.     ... again, part of proper 3D painting
  867. }
  868. }
  869. begin
  870.  
  871.    if (not BWCCClassNames) and UseCtl3d and B3D and IsModal and
  872.         Assigned(@Ctl3dDlgFramePaint)
  873.    then
  874.         With Msg
  875.        do
  876.       begin
  877.  
  878.             SetWindowLong(HWindow,dwl_MsgResult,
  879.                               Ctl3dDlgFramePaint(HWindow,Message,wParam,lParam));
  880.             Result := 1
  881.  
  882.       end
  883.    else
  884.        DefWndProc(Msg)
  885.  
  886. end;
  887.  
  888. {****************************************************************************}
  889. {*                                                                          *}
  890. {* Object:   T3dMDIWindow                                                   *}
  891. {*                                                                          *}
  892. {* Replacement object for TMDIWindow. Processes wm_SysColorChange to ensure *}
  893. {* CTL3D is kept up to date on desktop color scheme.                        *}
  894. {*                                                                          *}
  895. {****************************************************************************}
  896.  
  897. {* -------------------- T3dMDIWindow.WMSysColorChange --------------------- *}
  898.  
  899. Procedure T3dMDIWindow.WMSysColorChange (var Msg : TMessage);
  900. {
  901.     Tell CTL3D of the new desktop color scheme
  902. }
  903. begin
  904.  
  905.    if UseCtl3d
  906.    then
  907.        Ctl3dColorChange
  908.  
  909. end;
  910.  
  911. {****************************************************************************}
  912. {*                                                                          *}
  913. {* Object:   T3dWindow                                                      *}
  914. {*                                                                          *}
  915. {* Replacement object for TWindow. Processes wm_SysColorChange to ensure    *}
  916. {* CTL3D is kept up to date on desktop color scheme.                        *}
  917. {*                                                                          *}
  918. {****************************************************************************}
  919.  
  920. {* ---------------------- T3dWindow.WMSysColorChange ---------------------- *}
  921.  
  922. Procedure T3dWindow.WMSysColorChange (var Msg : TMessage);
  923. {
  924.     Tell CTL3D of the new desktop color scheme
  925. }
  926. begin
  927.  
  928.    if UseCtl3d
  929.    then
  930.        Ctl3dColorChange
  931.  
  932. end;
  933.  
  934. {****************************************************************************}
  935. {*                                                                          *}
  936. {* Unit initialisation. Get Windows version number, and note whether we are *}
  937. {* running under Windows 3.0.                                               *}
  938. {*                                                                          *}
  939. {****************************************************************************}
  940.  
  941. begin
  942.  
  943.    WinVersion := GetVersion;
  944.     Win30 := (lo(WinVersion) = 3) and (hi(WinVersion) < 10)
  945.  
  946. end.
  947.